<template>
	<el-dialog
		v-model="dialogVisible"
		title="选择常用菜单"
		width="1200px"
		:before-close="handleClose"
		destroy-on-close
		:close-on-click-modal="true"
		class="menu-selector-dialog"
	>
		<div class="menu-selector-container">
			<!-- 搜索栏 -->
			<div class="search-bar">
				<el-input v-model="searchKeyword" placeholder="搜索菜单..." :prefix-icon="Search" clearable @input="handleSearch" class="search-input" />
			</div>

			<!-- 菜单展示区域 -->
			<div class="menu-content" v-loading="loading">
				<div v-if="filteredMenus.length === 0" class="empty-state">
					<el-icon class="empty-icon"><Collection /></el-icon>
					<div class="empty-text">{{ searchKeyword ? '未找到匹配的菜单' : '暂无可用菜单' }}</div>
				</div>

				<div v-else class="menu-groups">
					<div v-for="group in filteredMenus" :key="group.id" class="menu-group">
						<div class="group-header">
							<div class="group-title">
								<el-icon class="group-icon">
									<component :is="getIconComponent(group.icon)" v-if="group.iconType === 'element'" />
									<i v-else :class="group.icon"></i>
								</el-icon>
								<span class="group-name">{{ group.name }}</span>
								<span class="group-count">({{ group.children.length }})</span>
							</div>
						</div>

						<div class="menu-items">
							<div
								v-for="item in group.children"
								:key="item.id"
								class="menu-item"
								:class="{ 'is-added': isMenuAdded(item) }"
								@click="handleMenuSelect(item)"
							>
								<div class="item-content">
									<div class="item-icon">
										<el-icon v-if="item.iconType === 'element'">
											<component :is="getIconComponent(item.icon)" />
										</el-icon>
										<i v-else :class="item.icon"></i>
									</div>
									<div class="item-info">
										<div class="item-name">{{ item.name }}</div>
										<div class="item-path">{{ item.path }}</div>
									</div>
								</div>
								<div class="item-actions">
									<el-button v-if="!isMenuAdded(item)" type="primary" size="small" :icon="Plus" @click.stop="handleAddShortcut(item)">
										添加
									</el-button>
									<el-tag v-else type="success" size="small">
										<el-icon><Check /></el-icon>
										已添加
									</el-tag>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<template #footer>
			<div class="dialog-footer">
				<div class="footer-info">
					<span class="selected-count">已添加 {{ addedCount }} 个常用菜单</span>
				</div>
				<div class="footer-actions">
					<el-button @click="handleClose">关闭</el-button>
				</div>
			</div>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, defineEmits } from 'vue';
import { ElMessage } from 'element-plus';
import {
	Search,
	Collection,
	Plus,
	Check,
	User,
	Calendar,
	Money,
	Bell,
	CircleCheck,
	Clock,
	Document,
	Promotion,
	Setting,
	Management,
	DataLine,
	Shop,
	Files,
	MessageBox,
} from '@element-plus/icons-vue';
import type { Component } from 'vue';
import mittBus from '/@/utils/mitt';

interface MenuItem {
	id: string;
	name: string;
	path: string;
	icon: string;
	iconType?: 'element' | 'custom';
	parentId?: string;
	children?: MenuItem[];
}

interface MenuGroup {
	id: string;
	name: string;
	icon: string;
	iconType?: 'element' | 'custom';
	children: MenuItem[];
}

interface Props {
	modelValue: boolean;
	menuList: any[];
	existingShortcuts: any[];
}

const props = defineProps<Props>();
const emit = defineEmits<{
	'update:modelValue': [value: boolean];
	'add-shortcut': [menuItem: MenuItem];
}>();

// 响应式数据
const loading = ref(false);
const searchKeyword = ref('');
const processedMenus = ref<MenuGroup[]>([]);

// 计算属性
const dialogVisible = computed({
	get: () => props.modelValue,
	set: (value: boolean) => emit('update:modelValue', value),
});

const filteredMenus = computed(() => {
	if (!searchKeyword.value.trim()) {
		return processedMenus.value;
	}

	const keyword = searchKeyword.value.toLowerCase();
	return processedMenus.value
		.map((group) => ({
			...group,
			children: group.children.filter((item) => item.name.toLowerCase().includes(keyword) || item.path.toLowerCase().includes(keyword)),
		}))
		.filter((group) => group.children.length > 0);
});

const addedCount = computed(() => {
	return props.existingShortcuts.length;
});

// 图标组件映射
const iconComponentMap: Record<string, Component> = {
	User,
	Calendar,
	Money,
	Bell,
	CircleCheck,
	Clock,
	Document,
	Promotion,
	Setting,
	Management,
	DataLine,
	Shop,
	Files,
	MessageBox,
};

// 方法
const getIconComponent = (iconName: string): Component => {
	// 如果是 ele- 开头的，提取实际的图标名称
	if (iconName?.startsWith('ele-')) {
		const actualIconName = iconName.replace('ele-', '');
		return iconComponentMap[actualIconName] || User;
	}
	return iconComponentMap[iconName] || User;
};

const isMenuAdded = (menuItem: MenuItem): boolean => {
	return props.existingShortcuts.some((shortcut) => shortcut.MenuId === menuItem.id || shortcut.MenuUrl === menuItem.path);
};

const processMenuList = () => {
	loading.value = true;
	try {
		const groups: MenuGroup[] = [];

		props.menuList.forEach((route: any) => {
			// 跳过隐藏的菜单项
			if (route.meta?.isHide) return;

			// 处理有子菜单的父级菜单
			if (route.children && route.children.length > 0) {
				const children: MenuItem[] = [];

				route.children.forEach((child: any) => {
					if (!child.meta?.isHide) {
						// 判断图标类型
						const iconType = child.meta?.icon?.startsWith('ele-') ? 'element' : 'custom';

						children.push({
							id: child.name || child.path,
							name: child.meta?.title || child.name || child.path,
							path: child.path,
							icon: child.meta?.icon || 'fa fa-file',
							iconType,
							parentId: route.name,
						});
					}
				});

				if (children.length > 0) {
					// 判断父级菜单图标类型
					const parentIconType = route.meta?.icon?.startsWith('ele-') ? 'element' : 'custom';

					groups.push({
						id: route.name || route.path,
						name: route.meta?.title || route.name || route.path,
						icon: route.meta?.icon || 'fa fa-folder',
						iconType: parentIconType,
						children,
					});
				}
			} else {
				// 处理没有子菜单的单独菜单项
				const iconType = route.meta?.icon?.startsWith('ele-') ? 'element' : 'custom';

				const existingGroup = groups.find((g) => g.id === 'others');
				const menuItem: MenuItem = {
					id: route.name || route.path,
					name: route.meta?.title || route.name || route.path,
					path: route.path,
					icon: route.meta?.icon || 'fa fa-file',
					iconType,
				};

				if (existingGroup) {
					existingGroup.children.push(menuItem);
				} else {
					groups.push({
						id: 'others',
						name: '其他功能',
						icon: 'fa fa-th',
						iconType: 'custom',
						children: [menuItem],
					});
				}
			}
		});

		processedMenus.value = groups;
	} catch (error) {
		console.error('处理菜单列表失败:', error);
		ElMessage.error('加载菜单失败');
	} finally {
		loading.value = false;
	}
};

const handleSearch = () => {
	// 搜索逻辑已在计算属性中处理
};

const handleMenuSelect = (menuItem: MenuItem) => {
	if (!isMenuAdded(menuItem)) {
		handleAddShortcut(menuItem);
	}
};

const handleAddShortcut = (menuItem: MenuItem) => {
	if (isMenuAdded(menuItem)) {
		ElMessage.warning('该菜单已添加到常用功能中');
		return;
	}

	emit('add-shortcut', menuItem);

	// 通知其他组件刷新常用功能
	mittBus.emit('refreshShortcuts');
};

const handleClose = () => {
	dialogVisible.value = false;
	searchKeyword.value = '';
};

// 监听器
watch(
	() => props.modelValue,
	(newValue) => {
		if (newValue && props.menuList.length > 0) {
			processMenuList();
		}
	}
);

watch(
	() => props.menuList,
	() => {
		if (props.modelValue) {
			processMenuList();
		}
	},
	{ deep: true }
);
</script>

<style scoped lang="scss">
.menu-selector-dialog {
	:deep(.el-dialog) {
		border-radius: 12px;
		box-shadow: 0 12px 48px rgba(0, 0, 0, 0.15);
	}

	:deep(.el-dialog__header) {
		background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
		color: white;
		border-radius: 12px 12px 0 0;
		padding: 20px 24px 16px;

		.el-dialog__title {
			font-size: 18px;
			font-weight: 600;
		}

		.el-dialog__headerbtn {
			.el-dialog__close {
				color: white;
				font-size: 18px;

				&:hover {
					color: rgba(255, 255, 255, 0.8);
				}
			}
		}
	}

	:deep(.el-dialog__body) {
		padding: 0;
		height: 600px;
		overflow: hidden;
	}

	:deep(.el-dialog__footer) {
		border-top: 1px solid var(--el-border-color-light);
		background: var(--el-bg-color-page);
		border-radius: 0 0 12px 12px;
	}
}

.menu-selector-container {
	height: 100%;
	display: flex;
	flex-direction: column;
}

.search-bar {
	padding: 20px 24px 16px;
	border-bottom: 1px solid var(--el-border-color-lighter);
	background: var(--el-bg-color);

	.search-input {
		:deep(.el-input__wrapper) {
			border-radius: 8px;
			box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
			transition: all 0.3s ease;

			&:hover,
			&.is-focus {
				box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
			}
		}
	}
}

.menu-content {
	flex: 1;
	overflow-y: auto;
	padding: 16px 24px 20px;

	&::-webkit-scrollbar {
		width: 6px;
	}

	&::-webkit-scrollbar-track {
		background: var(--el-fill-color-lighter);
		border-radius: 3px;
	}

	&::-webkit-scrollbar-thumb {
		background: var(--el-fill-color-dark);
		border-radius: 3px;

		&:hover {
			background: var(--el-fill-color-darker);
		}
	}
}

.empty-state {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	height: 300px;
	color: var(--el-text-color-secondary);

	.empty-icon {
		font-size: 64px;
		margin-bottom: 16px;
		color: var(--el-text-color-placeholder);
	}

	.empty-text {
		font-size: 16px;
	}
}

.menu-groups {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.menu-group {
	background: var(--el-bg-color);
	border-radius: 12px;
	border: 1px solid var(--el-border-color-lighter);
	overflow: hidden;
	transition: all 0.3s ease;

	&:hover {
		box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
	}
}

.group-header {
	background: linear-gradient(135deg, var(--el-color-primary-light-9) 0%, var(--el-color-primary-light-8) 100%);
	padding: 16px 20px;
	border-bottom: 1px solid var(--el-border-color-lighter);

	.group-title {
		display: flex;
		align-items: center;
		gap: 12px;
		font-weight: 600;
		font-size: 16px;
		color: var(--el-color-primary);

		.group-icon {
			width: 24px;
			height: 24px;
			display: flex;
			align-items: center;
			justify-content: center;
			background: var(--el-color-primary);
			color: white;
			border-radius: 6px;
			font-size: 14px;
		}

		.group-name {
			flex: 1;
		}

		.group-count {
			font-size: 14px;
			color: var(--el-text-color-secondary);
			font-weight: normal;
		}
	}
}

.menu-items {
	padding: 8px;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
	gap: 8px;
}

.menu-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 12px 16px;
	border-radius: 8px;
	cursor: pointer;
	transition: all 0.3s ease;
	border: 1px solid transparent;

	&:hover {
		background: var(--el-color-primary-light-9);
		border-color: var(--el-color-primary-light-7);
		transform: translateY(-1px);
	}

	&.is-added {
		background: var(--el-color-success-light-9);
		border-color: var(--el-color-success-light-7);
		cursor: default;

		&:hover {
			transform: none;
		}
	}

	.item-content {
		display: flex;
		align-items: center;
		gap: 12px;
		flex: 1;
		min-width: 0;
	}

	.item-icon {
		width: 36px;
		height: 36px;
		background: var(--el-color-primary-light-8);
		border-radius: 8px;
		display: flex;
		align-items: center;
		justify-content: center;
		color: var(--el-color-primary);
		font-size: 16px;
		flex-shrink: 0;

		.el-icon {
			font-size: 16px;
		}
	}

	.item-info {
		flex: 1;
		min-width: 0;

		.item-name {
			font-weight: 500;
			color: var(--el-text-color-primary);
			margin-bottom: 4px;
			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
		}

		.item-path {
			font-size: 12px;
			color: var(--el-text-color-secondary);
			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
		}
	}

	.item-actions {
		flex-shrink: 0;
		margin-left: 12px;
	}

	&.is-added {
		.item-icon {
			background: var(--el-color-success-light-8);
			color: var(--el-color-success);
		}
	}
}

.dialog-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 16px 24px;

	.footer-info {
		.selected-count {
			font-size: 14px;
			color: var(--el-text-color-secondary);
		}
	}

	.footer-actions {
		display: flex;
		gap: 12px;
	}
}

// 响应式设计
@media (max-width: 768px) {
	.menu-selector-dialog {
		:deep(.el-dialog) {
			width: 95vw !important;
			margin: 20px auto;
		}
	}

	.menu-items {
		grid-template-columns: 1fr;
	}

	.item-info {
		.item-name,
		.item-path {
			white-space: normal;
			overflow: visible;
			text-overflow: initial;
		}
	}
}

@media (max-width: 480px) {
	.search-bar,
	.menu-content {
		padding-left: 16px;
		padding-right: 16px;
	}

	.group-header {
		padding: 12px 16px;

		.group-title {
			font-size: 14px;

			.group-icon {
				width: 20px;
				height: 20px;
				font-size: 12px;
			}
		}
	}

	.menu-item {
		flex-direction: column;
		align-items: stretch;
		gap: 12px;

		.item-content {
			justify-content: flex-start;
		}

		.item-actions {
			margin-left: 0;
			align-self: flex-end;
		}
	}
}
</style>
